package com.xia.util.websocket;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

//websocket入口
@ServerEndpoint("/websocket/{usersId}")
@Slf4j
@Component
public class Websocket {
    //静态变量，用来记录当前在线连接数。设计为安全的
    private static int onlineCount = 0;
    //concurrentHashMap分段锁，用来存放每个客户端对应的Websocket对象。
    private static Map<String, Websocket> clients = new ConcurrentHashMap<String, Websocket>();
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    private String usersId;
    private static RedisTemplate<String,Object> redisTemplate;

    @Resource
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        Websocket.redisTemplate = redisTemplate;
    }


    /**
     * 连接建立成功调用的方法
     * @param usersId 用户ID
     * @param session 连接会话
     */
    @OnOpen
    public void onOpen(@PathParam("usersId") String usersId, Session session) throws IOException {
        if (clients.containsKey(usersId)){
            return;
        }
        this.usersId = usersId;
        this.session = session;
        Websocket.onlineCount++;
        log.info("有一连接进入！当前在线人数为" + onlineCount);
        clients.put(usersId, this);
        onMessage("开始");
    }

    /**
     * 若有人给某人发送了信息则根据某人的ID推送消息
     * @param usersId 被推送消息
     */
    public static void sendMessage(String usersId,String message) throws IOException {
        boolean state=clients.containsKey(usersId);
        if (state){
            Websocket websocket=clients.get(usersId);
            websocket.session.getBasicRemote().sendText(message);
        }
    }
    public static void sendMessage(String usersId, Object o) throws IOException, EncodeException {
        boolean state=clients.containsKey(usersId);
        if (state){
            Websocket websocket=clients.get(usersId);
            websocket.session.getBasicRemote().sendObject(JSON.toJSONString(o));
        }
    }

    /**
     * 获取前端主动发送的信息
     * @param message 接收信息
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        String userKey = "informUsersCommentId_" + usersId;
        Set<Object> set = redisTemplate.opsForSet().members(userKey);
        if (set.size() != 0) {
            session.getBasicRemote().sendText("有新消息哦~前往消息中心查看");
            /*session.getBasicRemote().sendObject(JSON.toJSONString(list));*/
            return;
        }
        session.getBasicRemote().sendText("没有新消息");
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        clients.remove(usersId);
        Websocket.onlineCount--;
        log.info("有一连接关闭！当前在线人数为" + onlineCount);
    }


    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("WebSocket发生错误：" + throwable);
    }

}